#pragma once
#include <iostream>
#include <string>
#include <functional>
#include "TcpServer.hpp"
#include "Socket.hpp"

#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>

using namespace std;
class TcpServer;
class Connection;
using func_t = function<void(Connection *)>;

class TcpServer;

class Connection
{
public:
    Connection(int sockfd,uint32_t events,TcpServer *R) : _sockfd(sockfd),_events(events),_R(R)
    {
    }
    void RegisterCallback(func_t recver, func_t sender, func_t execepter)
    {
        _recver=recver;
        _sender=sender;
        _execepter=execepter;
    }
    void AddInBuffer(string buffer)
    {
        _inbuffer+=buffer;
    }
    void AddOutbuffer(const string& buffer)
    {
        _outbuffer+=buffer;
    }
    bool OutBufferEmpty()
    {
        return _outbuffer.empty();
    }
    int SockFd()
    {
        return _sockfd;
    }
    uint32_t Events()
    {
        return _events;
    }
    void SetEvents(uint32_t events)
    {
        _events=events;
    }
    void SetClient(const struct sockaddr_in client)
    {
        _client=client;
    }
    string& InBuffer()
    {
        return _inbuffer;
    }
     string& OutBuffer()
    {
        return _outbuffer;
    }
    void Close()
    {
        close(_sockfd);
    }
    ~Connection() {}

private:
    int _sockfd;
    string _inbuffer;  //_sockfd 接收缓冲区，暂时用string替代（string只能处理字符串类型，一旦是图片等类型就无法处理）
    string _outbuffer; ////_sockfd 发送缓冲区

    // 关心事件
    uint32_t _events;

    //维护客户端信息
    struct sockaddr_in _client;

public:

     // TcpServer的回指指针
    TcpServer* _R;
    // 对特定connection进行处理的回调函数
    func_t _recver;
    func_t _sender;
    func_t _execepter;
};

class ConnectionFatory
{
public:
    static Connection *BuildListenConnection(int listensockfd, func_t recver,uint32_t events,TcpServer *R)
    {
        Connection* conn=new Connection(listensockfd,events,R);
        conn->RegisterCallback(recver, nullptr, nullptr);
        return conn;
    }
    static Connection* BuildNormalConnection(int sockfd, func_t recver, func_t sender, func_t execepter,uint32_t events,TcpServer *R)
    {
        Connection* conn=new Connection(sockfd,events,R);
        conn->RegisterCallback(recver, sender, execepter);
        return conn;
    }
};
